-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2
--
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.

-- Desription: 事件管理
local cjson = require "cjson"
local utils = require 'mc.utils'

local level = {
    ['Normal'] = 'Informational',
    ['Minor'] = 'Minor',
    ['Major'] = 'Major',
    ['Critical'] = 'Critical'
}

local severity = {
    ['Normal'] = 'OK',
    ['Minor'] = 'Warning',
    ['Major'] = 'Warning',
    ['Critical'] = 'Critical'
}

local m = {}

local function format_event_list(event_list)
    if #event_list == 0 then
        return {}
    end
    -- 计算结构体参数个数
    local num = 0
    local end_flag = event_list[1].MappingTable[1].Key
    for key, value in pairs(event_list) do
        if value.MappingTable[1].Key == end_flag and key ~= 1 then
            break
        end
        num = num + 1
    end
    -- 格式化结构体,num个结构体构成一条Sel
    local count = 0
    local res = {}
    local event = {}
    for _, v in pairs(event_list) do
        event[v.MappingTable[1].Key] = v.MappingTable[1].Value
        count = count + 1
        if count % num == 0 then
            local temp = event
            event = {}
            res[#res + 1] = temp
        end
    end
    return res
end

local function insertinto_healthevent_list(index, healthEvent, event, major_v, minor_v)
    healthEvent[index] = cjson.json_object_new_object()
    healthEvent[index].EventType = 'Alert'
    healthEvent[index].EntryType = 'Event'
    healthEvent[index].EventSubject = event.ComponentName
    healthEvent[index].Created = utils.date_format(event.Timestamp, '%Y-%m-%dT%H:%M:%S', true)
    healthEvent[index].Severity = severity[event.Severity]
    healthEvent[index].Level = level[event.Severity]
    healthEvent[index].Message = event.Description
    healthEvent[index].HandlingSuggestion = event.Suggestion
    healthEvent[index].EventId = event.EventCode

    if event.SystemId == '' or event.SystemId == '0' then
        healthEvent[index].SystemId = cjson.null
    else
        healthEvent[index].SystemId = event.SystemId
    end

    healthEvent[index].MessageId = string.format('iBMCEvents.%s.%s.%s', major_v, minor_v, event.EventName)
    local ok, messgage_args = pcall(function ()
        return cjson.decode(event.MessageArgs)
    end)
    if ok then
        local tmp_table = cjson.json_object_new_array()
        for _, value in pairs(messgage_args) do
            tmp_table[#tmp_table + 1] = value
        end
        healthEvent[index].MessageArgs = tmp_table
    else
        healthEvent[index].MessageArgs = cjson.json_object_new_array()
    end
end

-- 获取事件主体列表
function m.get_object_type_list(component_types)
    local object_type_list = cjson.json_object_new_array()
    for _, obj in ipairs(component_types) do
        local object_type = cjson.json_object_new_object()
        object_type.ObjectTypeId = obj.ComponentType
        object_type.ObjectTypeLabel = obj.ComponentName
        object_type_list[#object_type_list + 1] = object_type
    end
    return object_type_list
end

-- 格式化版本号
function m.get_event_version(str, destination)
    return string.format(str, destination.MajorVersion, destination.MinorVersion, destination.AuxVersion)
end

function m.get_HealthEvent(processobj, eventsinfo)
    local data_source = processobj.EventList
    local eventlist = format_event_list(data_source)
    local major_v = eventsinfo.MajorVersion
    local minor_v = eventsinfo.MinorVersion

    local healthEvent = cjson.json_object_new_array()

    if type(eventlist) == 'userdata' or #eventlist == 0 then
        return healthEvent
    end

    for i, _ in ipairs(eventlist) do
        insertinto_healthevent_list(i, healthEvent, eventlist[i], major_v, minor_v)
    end

    return healthEvent
end

return m
